//
//  PathAnimationView.m
//  CoreAnimation
//
//  Created by LG on 2018/5/17.
//  Copyright © 2018年 iqiyi. All rights reserved.
//

#import "PathAnimationView.h"
#import "UIButton+Extend.h"

@interface PathAnimationView()

@property (nonatomic, weak) UIButton *btn_center;
@property (nonatomic, assign) BOOL innerStatusBomb;

@end

@implementation PathAnimationView

void addButtonAction(id target, UIButton *btn,SEL selctor, UIControlEvents event)
{
    [btn addTarget:target action:selctor forControlEvents:event];
}

#pragma mark -- inherit
- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self setupBasicView];
    }
    return self;
}

#pragma mark -- Public
- (void)setOptions:(NSMutableArray<UIButton *> *)options
{
    [self validateOptions:options];
    
    if (options && [options isKindOfClass:[NSMutableArray class]] && options.count) {
        _options = [NSMutableArray arrayWithArray:options];
        [self cleaSubviews];
        [self setupSubviews];
    } else {
        NSAssert(1, @"参数传入错误");
    }
}

#pragma mark -- UI

- (void)cleaSubviews
{
    NSArray *subviews = self.subviews;
    for (NSInteger i = 0; i < subviews.count; i++) {
        UIView *view = subviews[i];
        if (view != self.btn_center) {
            [view removeFromSuperview];
        }
    }
}

- (void)setupBasicView
{
    UIButton *btn_center = [UIButton buttonWithType:UIButtonTypeCustom];
    [btn_center setTitle:@"+" forState:UIControlStateNormal];
    btn_center.frame = CGRectMake(100, 100, 30, 30);
    btn_center.center = self.center;
    btn_center.backgroundColor = [UIColor redColor];
    [self addSubview:btn_center];
    self.btn_center = btn_center;
    
    [self.btn_center addTarget:self action:@selector(btnClickCenter) forControlEvents:UIControlEventTouchUpInside];
}

- (void)setupSubviews
{
    for (NSInteger i = 0; i < self.options.count; i++) {
        UIButton *btn = self.options[i];
        btn.frame = self.btn_center.frame;
        btn.layer.cornerRadius = CGRectGetWidth(btn.bounds)/2.;
        btn.layer.masksToBounds = YES;
        [self insertSubview:btn belowSubview:self.btn_center];
        addButtonAction(self,btn, @selector(btnClickOption:),UIControlEventTouchUpInside);
    }
}

#pragma mark -- Actions
- (void)btnClickOption:(UIButton*)btn
{
    NSMutableArray *items = [NSMutableArray arrayWithArray:self.options];
    [items removeObject:btn];
    
    [UIView animateWithDuration:0.0618f * items.count
                     animations:^{
                         btn.transform = CGAffineTransformMakeScale(3, 3);
                         btn.alpha = 0.0f;
                     } completion:^(BOOL finished) {
                         btn.transform = CGAffineTransformIdentity;
                         btn.center = self.btn_center.center;
                         btn.alpha = 1.0f;
                     }];
    
    // Excute the dismiss animation when the item is unselected
    //
    for (int i = 0; i < items.count; i++) {
        UIButton *unselectedButton = items[i];
        [UIView animateWithDuration:0.0618f * 2
                         animations:^{
                             unselectedButton.transform = CGAffineTransformMakeScale(0, 0);
                         } completion:^(BOOL finished) {
                             unselectedButton.center = self.btn_center.center;
                             unselectedButton.transform = CGAffineTransformIdentity;
                         }];
    }
    
    self.innerStatusBomb = NO;
}

- (void)btnClickCenter
{
    if (self.innerStatusBomb) {
        [self foldOptions:self.options];
    } else {
        [self bombOptions:self.options];
    }
}

#pragma mark -- Tools

- (void)foldOptions:(NSArray*)options
{
    [CATransaction begin];
    [CATransaction setAnimationDuration:.5];
    
    for (NSInteger i = 0; i < options.count; i++) {
        UIButton *btn = options[i];
        CAAnimationGroup *group = [self foldAnimationGroupWithStartPoint:btn.center];
        [btn.layer addAnimation:group forKey:@"foldAnimation"];
        btn.center = self.btn_center.center;
    }
    
    [CATransaction setCompletionBlock:^{
        for (NSInteger i = 0; i < options.count; i++) {
            UIButton *btn = options[i];
            CGPoint endPoint = self.btn_center.center;
            btn.center = endPoint;
        }
        self.innerStatusBomb = NO;
    }];
    
    [CATransaction commit];
}

- (void)bombOptions:(NSArray*)options
{
    [CATransaction begin];
    [CATransaction setAnimationDuration:.5];
    
    CGFloat radious = 80;//距离中点的距离
    for (NSInteger i = 0; i < options.count; i++) {
        UIButton *btn = options[i];
        CGPoint endPoint = [self obtainViewCenterPoint:self.btn_center.center radious:radious index:i totalNum:options.count];
        CAAnimationGroup *group = [self bombAnimationGroupWithEndPoint:endPoint];
        group.delegate = self;
        [btn.layer addAnimation:group forKey:@""];
    }
    
    [CATransaction setCompletionBlock:^{
        CGFloat radious = 80;//距离中点的距离
        for (NSInteger i = 0; i < options.count; i++) {
            UIButton *btn = options[i];
            CGPoint endPoint = [self obtainViewCenterPoint:self.btn_center.center radious:radious index:i totalNum:options.count];
            btn.center = endPoint;
        }
        self.innerStatusBomb = YES;
    }];
    
    [CATransaction commit];
}

/**
 验证传入的选项
 */
- (void)validateOptions:(NSMutableArray*)array
{
    for (NSInteger i = 0; i < array.count; i++) {
        UIButton *btn = array[i];
        if (!btn || ![btn isKindOfClass:[UIButton class]]) {
            [array removeObject:btn];
        }
    }
}


/**
 选中选项的点击动画

 @param point 开始的点
 @return 动画组
 */
- (CAAnimationGroup*)chosedOptionAnimationWithStart:(CGPoint)point
{
    CAKeyframeAnimation *pathAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    UIBezierPath *bezierPath = [UIBezierPath bezierPath];
    [bezierPath moveToPoint:point];
    [bezierPath addLineToPoint:self.btn_center.center];
    pathAnimation.path = bezierPath.CGPath;
    pathAnimation.beginTime = .7;
    
    CAKeyframeAnimation *rotationAni = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale"];
    rotationAni.values = @[@(1.2),@(1)];
    rotationAni.keyTimes = @[@.0,@5];
    
    CAAnimationGroup *group = [CAAnimationGroup animation];
    group.animations = @[pathAnimation,rotationAni];
    group.duration = 1;
    
    return group;
}

- (CAAnimationGroup*)bombAnimationGroupWithEndPoint:(CGPoint)endPoint
{
    CAKeyframeAnimation *pathAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    UIBezierPath *bezierPath = [UIBezierPath bezierPath];
    [bezierPath moveToPoint:self.btn_center.center];
    [bezierPath addLineToPoint:endPoint];
    pathAnimation.path = bezierPath.CGPath;
    
    CAKeyframeAnimation *rotationAni = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation"];
    rotationAni.values = @[@(0),@(M_PI),@(0)];
    rotationAni.keyTimes = @[@0,@.5,@1];
    
    CAAnimationGroup *group = [CAAnimationGroup animation];
    group.animations = @[pathAnimation,rotationAni];
    group.duration = .5;
    
    return group;
}

- (CAAnimationGroup*)foldAnimationGroupWithStartPoint:(CGPoint)point
{
    CAKeyframeAnimation *pathAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    UIBezierPath *bezierPath = [UIBezierPath bezierPath];
    [bezierPath moveToPoint:point];
    [bezierPath addLineToPoint:self.btn_center.center];
    pathAnimation.path = bezierPath.CGPath;
    
    CAKeyframeAnimation *rotationAni = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation"];
    rotationAni.values = @[@(0),@(M_PI_2),@(M_PI)];
    rotationAni.keyTimes = @[@0,@.4,@1];
    
    CAAnimationGroup *group = [CAAnimationGroup animation];
    group.animations = @[pathAnimation,rotationAni];
    group.duration = 5;
    
    return group;
}

- (CGPoint)obtainViewCenterPoint:(CGPoint)origin radious:(CGFloat)radious index:(NSInteger)index totalNum:(NSInteger)count
{
    CGFloat basicAngle = M_PI / (count + 1);
    CGFloat currentAngel = basicAngle * (index + 1);
    CGFloat x = origin.x;
    CGFloat y = origin.y - sinf(currentAngel) * radious;
    if (index <= count / 2.) {
        x = origin.x - cosf(currentAngel) * radious;
    } else {
        x = origin.x + cosf(M_PI - currentAngel) * radious;
    }
    
    return CGPointMake(x, y);
}

@end
